/*
 * Copyright (c) Huawei Device Co., Ltd. 2024. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef EF_PARSER_H
#define EF_PARSER_H

#include <string>
#include <vector>

namespace OHOS {
namespace SE {
static const uint16_t APDU_SUCCESS = 0x9000;

class EfParser : public std::enable_shared_from_this<EfParser> {
public:
    EfParser();
    ~EfParser();

    /**
     * @brief Read file data by specific file path
     * @param path Read file name
     * @param rspApdu Output response apdu (e.g. 0x9000)
     * @return Is file succefully read
     */
    bool ReadFileByPath(const std::vector<uint8_t> &path, uint16_t &rspApdu);

    /**
     * @brief Read file data by specific data size
     * @param dataOffset File data offset
     * @param dataSize File data size
     * @return File data read from secure element hardware
     */
    std::vector<uint8_t> ReadFileByDataSize(uint32_t dataOffset, int dataSize);

    /**
     * @brief Read file record by record order
     * @param record Record data order
     * @return File data record from secure element hardware
     */
    std::vector<uint8_t> ReadFileRecord(uint8_t record);

    /**
     * @brief Get current reading file id
     * @return Cureent reading file id
     */
    int GetFileId();

    /**
     * @brief Get current reading file path
     * @return Cureent reading file path
     */
    std::vector<uint8_t> GetFilePath();

    /**
     * @brief Get current reading record number
     * @return Cureent reading record number
     */
    uint8_t GetFileRecordNumber();

private:
    void ParseFileData(const std::vector<uint8_t> &response);
    void ParseSIMFileInfo(const std::vector<uint8_t> &response);
    void ParseUSIMFileData(const std::vector<uint8_t> &response);
    void ParseUSIMFileDataSize(const std::vector<uint8_t> &tlvData);
    void ParseUSIMFileInfo(const std::vector<uint8_t> &tlvData);
    void ResetFileInfo();

    // reference: GlobalPlatform Device Technology Secyre Element Access Control Spec.
    static const uint8_t FILE_TYPE_EF = 0x04;
    static const uint8_t FILE_TYPE_UNKNOWN = 0xFF;
    static const uint8_t FILE_STRUCTURE_TRANSPARENT = 0x00;
    static const uint8_t FILE_STRUCTURE_LINEAR_FIXED = 0x01;
    static const uint8_t FILE_STRUCTURE_UNKNOWN = 0xFF;
    static const uint8_t TLV_TYPE_FILE_SIZE = 0x80;
    static const uint8_t TLV_TYPE_FILE_INFO = 0x82;

    uint8_t fileType_ = FILE_TYPE_UNKNOWN;
    uint8_t fileStructType_ = FILE_STRUCTURE_UNKNOWN;
    uint8_t fileRecordNum_;
    int fileId_;
    int fileDataSize_;
    int fileRecordSize_;
    std::vector<uint8_t> filePath_ {};
};
}  // namespace SE
}  // namespace OHOS
#endif // EF_PARSER_H